home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 2010 April / PCWorld0410.iso / pluginy Firefox / 1122 / 1122.xpi / chrome / tabmixplus.jar / content / tabmixplus / minit / tablib.js < prev   
Text File  |  2009-10-12  |  73KB  |  1,951 lines

  1. // code modified by Hemiola SUN, 2005-04-14 and fixed by onemen
  2. if(!window.tablib || tablib.version != "tabmixplus")
  3. var tablib = {
  4. version : "tabmixplus",
  5. _inited: false,
  6.  
  7. init : function() {
  8. if (this._inited)
  9.   return;
  10. this._inited = true;
  11.  
  12. if(gBrowser.mTabs.length > 0)
  13.   gBrowser.mCurrentTab._selected = true;
  14.  
  15. // NRA-ILA toolbar extension raplce the original addTab function
  16. var _addTab = "addTab";
  17. if ("origAddTab7c3de167ed6f494aa652f11a71ecb40c" in gBrowser)
  18.   _addTab = "origAddTab7c3de167ed6f494aa652f11a71ecb40c";
  19.  
  20. eval("gBrowser." + _addTab + " =" + gBrowser[_addTab].toString().replace(
  21. 'var blank = aURI == "about:blank";',
  22. 'var blank = !aURI || aURI == "about:blank";'
  23. ).replace(
  24. 't.setAttribute("label", aURI);',
  25. 't.setAttribute("label", gWidthFitTitle ? this.mStringBundle.getString("tabs.loading") : aURI);'
  26. ).replace(
  27. 't.width = 0;',
  28. 't.style.maxWidth = t.maxWidth + "px";'
  29. ).replace(
  30. 't.setAttribute("flex", "100");',
  31. 'if (!gWidthFitTitle) { \
  32.    t.width = 0; \
  33.    $& \
  34.  } else t.setAttribute("newtab", "true");'
  35. ).replace(
  36. 't.dispatchEvent(evt);',
  37. '$& this.TMP_openTabNext(t, arguments.callee.caller.name);'
  38. ).replace( /* Bug 465673 Change 'Default' Tab Opening Behavior/Position for Firefox - landed on 3.7a1pre 2009-09-05
  39.               we don't use it for now */
  40. 'this.mPrefs.getBoolPref("browser.tabs.insertRelatedAfterCurrent")',
  41. 'false'
  42. ));
  43.  
  44. // ContextMenu Extensions raplce the original removeTab function
  45. var _removeTab = "removeTab";
  46. if ("__ctxextensions__removeTab" in gBrowser)
  47.   _removeTab = "__ctxextensions__removeTab";
  48.  
  49. if (gIsFirefox35) {
  50.    // for Firefox 3.5+ //
  51.    eval("gBrowser." + _removeTab + " =" + gBrowser[_removeTab].toString().replace(
  52.       '{',
  53.       '{ \
  54.        if (this.mTabContainer.childNodes.length == 1 && this.mPrefs.getBoolPref("extensions.tabmix.keepLastTab")) return; \
  55.        if (aTab.hasAttribute("protected")) return;\
  56.        aTab.clearTimeouts();'
  57.    ));
  58.  
  59.   eval("gBrowser._endRemoveTab ="+gBrowser._endRemoveTab.toString().replace(
  60.     'aTab.collapsed = true;',
  61.     'if (this.mTabs.length == this._removingTabs.length) aTab.collapsed = true; \
  62.      else aTab.hidden = true;'
  63.   ).replace(
  64.     'this.addTab("about:blank");',
  65.     'TMP_BrowserOpenTab(null, true);'
  66.   ).replace(
  67.     'this._blurTab(aTab);',
  68.     'TMP_onRemoveTab(aTab, browser); \
  69.      this.mTabContainer.nextTab = 1; \
  70.      $&'
  71.   ));
  72.  
  73.   eval("gBrowser._blurTab ="+gBrowser._blurTab.toString().replace(
  74.     'if (aTab.owner &&',
  75.     'if (false &&'
  76.   ).replace(
  77.     'var tab = aTab;',
  78.     'var tab, newIndex = this.selectIndexAfterRemove(aTab);\
  79.      if (newIndex > -1) {\
  80.        tab = this.mTabContainer.childNodes[newIndex];\
  81.        if (tab && this._removingTabs.indexOf(tab) == -1) {\
  82.          this.selectedTab = tab;\
  83.          return;\
  84.        }\
  85.      }\
  86.      tab = aTab;'
  87.   ));
  88. }
  89. else {
  90.   // for Firefox 3.0 //
  91.   eval("gBrowser." + _removeTab + " =" + gBrowser[_removeTab].toString().replace(
  92.     'var l = this.mTabContainer.childNodes.length;',
  93.     'if (aTab.hasAttribute("protected")) return; \
  94.      aTab.clearTimeouts(); \
  95.      $&'
  96.   ).replace(
  97.     'var oldTab = aTab;',
  98.     '$& TMP_onRemoveTab(oldTab, oldBrowser); \
  99.      var tabmixIndex = this.selectIndexAfterRemove(oldTab); \
  100.      if (tabmixIndex > oldTab._tPos) tabmixIndex--;'
  101.   ).replace(
  102.     'this.selectedTab = this.mTabContainer.childNodes[newIndex];',
  103.     'this.mTabContainer.nextTab = 1; \
  104.      if (tabmixIndex > -1) newIndex = tabmixIndex; \
  105.      $&'
  106.   ).replace(
  107.     'this.addTab("about:blank");',
  108.     'if (this.mPrefs.getBoolPref("extensions.tabmix.keepLastTab")) \ return; \
  109.      aTab.collapsed = true; \
  110.      TMP_BrowserOpenTab(null, true);'
  111.   ));
  112. }
  113.  
  114. eval("gBrowser.mTabContainer._selectNewTab" + " ="+gBrowser.mTabContainer._selectNewTab.toString().replace(
  115. '{',
  116. '{if(!this.mPrefs.getBoolPref("extensions.tabmix.mouseDownSelect") && arguments.callee.caller.name == "setTab") return; '
  117. ));
  118.  
  119. eval("BrowserCloseTabOrWindow ="+BrowserCloseTabOrWindow.toString().replace(
  120. /closeWindow\(true\);/g,
  121. 'TMP_closeLastTab();'
  122. ).replace(
  123. /gBrowser.removeCurrentTab\(\);/g,
  124. 'TMP_closeLastTab();'
  125. ).replace(
  126. /gBrowser.removeCurrentTab\(true\);/g,
  127. 'TMP_closeLastTab();'
  128. ).replace(
  129. 'BrowserCloseWindow();',
  130. 'TMP_closeLastTab();'
  131. ));
  132.  
  133. //don't open link from external application in new window when in single window mode
  134. //don't open link from external application in current tab if the tab is locked
  135. var _openURI = nsBrowserAccess.prototype.openURI.toString();
  136. if (gIsFirefox35) {
  137.   // after Bug 324164 - Unify Single Window Mode Preferences
  138.   _openURI = _openURI.replace(
  139.     'aWhere = gPrefService.getIntPref("browser.link.open_newwindow");',
  140.     'if (isExternal) aWhere = TMP_getIntPref("", "browser.link.open_external",3); \
  141.      else $&'
  142.   ).replace(
  143.     'let loadBlankFirst =',
  144.     '$& currentIsBlank ||'
  145.   );
  146. }
  147. _openURI = _openURI.replace(
  148.   'switch (aWhere) {',
  149.   'if (gSingleWindowMode && aWhere == Ci.nsIBrowserDOMWindow.OPEN_NEWWINDOW) {\
  150.    aWhere = Ci.nsIBrowserDOMWindow.OPEN_NEWTAB;}\
  151.    if (aWhere != Ci.nsIBrowserDOMWindow.OPEN_NEWWINDOW && aWhere != Ci.nsIBrowserDOMWindow.OPEN_NEWTAB){\
  152.    var isLockTab = TMP_whereToOpen(null).lock; if(isLockTab) aWhere = Ci.nsIBrowserDOMWindow.OPEN_NEWTAB;}\
  153.    $&'
  154. ).replace(
  155.   '("browser.tabs.loadDivertedInBackground");',
  156.   '$& \
  157.    let currentIsBlank = win.gBrowser.isBlankNotBusyTab(win.gBrowser.mCurrentTab);'
  158. ).replace(
  159.   'win.gBrowser.loadOneTab',
  160.   'currentIsBlank ? win.gBrowser.mCurrentTab : $&'
  161. ).replace(
  162.   'if (needToFocusWin',
  163.   'if (currentIsBlank && !loadInBackground)\
  164.      win.content.focus();\
  165.    $&'
  166. );
  167. eval("nsBrowserAccess.prototype.openURI ="+_openURI);
  168.  
  169. //inverse focus of middle/ctrl/meta clicked links
  170. eval("openNewTabWith ="+openNewTabWith.toString().replace(
  171. 'if (aEvent && aEvent.shiftKey)',
  172. 'if (aEvent && (aEvent.button == 1 || aEvent.button == 0 && ( aEvent.ctrlKey || aEvent.metaKey )) && (prefSvc.getBoolPref("extensions.tabmix.inversefocusLinks") || !prefSvc.getBoolPref("extensions.tabmix.inversefocusLinks") && aEvent.shiftKey))'
  173. ));
  174.  
  175. eval("FillHistoryMenu ="+FillHistoryMenu.toString().replace(
  176. /entry.title/g,
  177. 'menuItemTitle(entry)'
  178. ));
  179.  
  180. // Chromin Frame put gBrowser.updateTitlebar in gChrominFrame._origupdateTitlebar
  181. var chrominFrame = "gChrominFrame" in window && "_origupdateTitlebar" in gChrominFrame;
  182. var fnName = chrominFrame ? "_origupdateTitlebar" : "updateTitlebar";
  183. var objName = chrominFrame ? "gChrominFrame" : "gBrowser";
  184. eval(objName + "." + fnName + " ="+window[objName][fnName].toString().replace(
  185. 'if (!docTitle)',
  186. 'var url = this.contentDocument.baseURI || this.currentURI.spec; \
  187.  if (this.mCurrentTab.getAttribute("label-uri") == url || this.mCurrentTab.getAttribute("label-uri") == "*") docTitle = this.mCurrentTab.getAttribute("fixed-label"); \
  188.  else docTitle = getTitleFromBookmark(url, docTitle, this.mCurrentTab.getAttribute("tabmix_bookmarkId")); \
  189.  $&'
  190. ));
  191.  
  192. eval("gBrowser.setTabTitle ="+gBrowser.setTabTitle.toString().replace(
  193. 'if (!title) {',
  194. 'if (gWidthFitTitle) { var cIndex = this.mTabContainer.selectedIndex; \
  195.  var currentTabVisible = this.mTabContainer.isTabVisible(cIndex); } \
  196.  var url = browser.contentDocument.baseURI || browser.currentURI.spec; \
  197.  if (aTab.getAttribute("label-uri") == url || aTab.getAttribute("label-uri") == "*") title = aTab.getAttribute("fixed-label"); \
  198.  else title = getTitleFromBookmark(url, title, aTab.getAttribute("tabmix_bookmarkId")); \
  199.  $&'
  200. ).replace(
  201.  'aTab.setAttribute("crop", crop);',
  202.  <![CDATA[$&
  203.     if (aTab.hasAttribute("mergeselected"))
  204.       aTab.label = "(*) " + aTab.label;
  205.     if (gWidthFitTitle) {
  206.       let width;
  207.       if (aTab.hasAttribute("width")) {
  208.         width = aTab.boxObject.width;
  209.         aTab.removeAttribute("width");
  210.       }
  211.       let newWidth = aTab.boxObject.width;
  212.       if (newWidth && newWidth != width) {
  213.         tabBarScrollStatus();
  214.         checkBeforeAndAfter();
  215.         if (currentTabVisible)
  216.           this.mTabContainer.ensureTabIsVisible(cIndex);
  217.       }
  218.     }
  219.  ]]>
  220. ));
  221.  
  222. eval("window.BrowserGoHome ="+window.BrowserGoHome.toString().replace(
  223. 'var where = whereToOpenLink(aEvent);',
  224. '$& \ if (where == "current" && TMP_whereToOpen(false).inNew) where = "tab";'
  225. ).replace(
  226. 'var where = whereToOpenLink(aEvent, false, true);',
  227. '$& \ if (where == "current" && TMP_whereToOpen(false).inNew) where = "tab";'
  228. ));
  229.  
  230. // before Firfox 3.6 newWindowButtonObserver.onDragOver return true and from version 3.6 return witout value
  231. var newString = gIsFirefox36 ? "return;" : "return true;";
  232. eval("newWindowButtonObserver.onDragOver ="+newWindowButtonObserver.onDragOver.toString().replace(
  233. '{',
  234. '{ \
  235.  if (gSingleWindowMode) { \
  236.     if (!aEvent.target.hasAttribute("disabled")) \
  237.        aEvent.target.setAttribute("disabled", true);\
  238.     NEWSTRING \
  239.  }'
  240. ).replace('NEWSTRING', newString));
  241.  
  242. eval("newWindowButtonObserver.onDrop ="+newWindowButtonObserver.onDrop.toString().replace(
  243. '{',
  244. '{ if (gSingleWindowMode) return;'
  245. ));
  246.  
  247. // fix webSearch to open new tab if tab is lock
  248. eval("BrowserSearch.webSearch ="+BrowserSearch.webSearch.toString().replace(
  249. 'loadURI(searchForm, null, null, false);',
  250. 'gBrowser.TMP_openURI(searchForm);'
  251. ));
  252.  
  253. gBrowser.TMP_openURI = function (uri) {
  254.    var openNewTab = TMP_whereToOpen(true).lock;
  255.    if (openNewTab)
  256.       this.loadOneTab(uri, null, null, null, false, false);
  257.    else
  258.       loadURI(uri, null, null, false);
  259. }
  260.  
  261. // Firefox 3.6 gIsFirefox36
  262. // warnAboutClosingWindow in window from Bug 354894 29/07/2009
  263. if ("warnAboutClosingWindow" in window) {
  264.   eval("warnAboutClosingWindow ="+warnAboutClosingWindow.toString().replace(
  265.     /return gBrowser.warnAboutClosingTabs\(true\);/g,
  266.     'return TMP_closeWindow(true);'
  267.   ).replace(
  268.     'os.notifyObservers(null, "browser-lastwindow-close-granted", null);',
  269.     'if (!(/^Mac/.test(navigator.platform)) && !TMP_closeWindow(true)) return false;\
  270.      $&'    
  271.   ));
  272.  
  273.   eval("closeWindow ="+closeWindow.toString().replace(
  274.     'else if (windowCount != 1',
  275.     'else if (windowCount == 1 && !inPrivateBrowsing && !TMP_closeWindow()) return false;\
  276.      $&'
  277.   ));
  278. }
  279. else {
  280.   /* For Firefox 3.0 */
  281.   eval("WindowIsClosing ="+WindowIsClosing.toString().replace(
  282.     'return closeWindow(false,',
  283.     'return TMP_closeWindow(); $&'
  284.   ).replace( // Firefox 3.5
  285.     'var reallyClose = closeWindow(false, function () {return gBrowser.warnAboutClosingTabs(true);});',
  286.     'var reallyClose = TMP_closeWindow();'
  287.   ));
  288. }
  289.  
  290. eval("goQuitApplication ="+goQuitApplication.toString().replace(
  291.   'var appStartup',
  292.   'if(!SessionManager.canQuitApplication()) \
  293.      return false; \
  294.    $&'
  295. ));
  296.  
  297. eval("HistoryMenu.toggleRecentlyClosedTabs ="+HistoryMenu.toggleRecentlyClosedTabs.toString().replace(
  298. 'if (ss.getClosedTabCount(window) == 0)',
  299. 'if (TMP_ClosedTabs.count == 0)'
  300. ));
  301.  
  302. // disable undo closed window when single window mode is on
  303. if (gIsFirefox35) {
  304. eval("HistoryMenu.toggleRecentlyClosedWindows ="+HistoryMenu.toggleRecentlyClosedWindows.toString().replace(
  305. 'if (this._ss.getClosedWindowCount() == 0)',
  306. 'if (this._ss.getClosedWindowCount() == 0 || gSingleWindowMode)'
  307. ));
  308.  
  309.   eval("HistoryMenu.populateUndoWindowSubmenu ="+HistoryMenu.populateUndoWindowSubmenu.toString().replace(
  310.     'var undoPopup = document.getElementById("historyUndoWindowPopup");',
  311.     'var id = arguments.length == 1 ? arguments[0] : "historyUndoWindowPopup"; \
  312.      var undoPopup = document.getElementById(id);'
  313.   ).replace(
  314.     'undoPopup.appendChild(m);',
  315.     'm.setAttribute("value", i); \
  316.      m.addEventListener("click", SessionManager.checkForMiddleClick, false); \
  317.      $&'
  318.   ).replace(
  319.     'm.id = "menu_restoreAllWindows";',
  320.     '$& \
  321.     m.setAttribute("value", -2);'
  322.   ).replace(
  323.     'var m = undoPopup.appendChild(document.createElement("menuitem"));',
  324.     '$& \
  325.      m.id = "menu_clearClosedWindowsList"; \
  326.      var strings = document.getElementById("tmp-string-bundle"); \
  327.      m.setAttribute("label", strings.getString("undoClosedWindows.clear.label")); \
  328.      m.setAttribute("accesskey", strings.getString("undoClosedWindows.clear.accesskey")); \
  329.      m.setAttribute("value", -1); \
  330.      m.setAttribute("oncommand", "SessionManager.forgetClosedWindow(-1);"); \
  331.      m = undoPopup.appendChild(document.createElement("menuitem"));'
  332.   ));
  333.  
  334.   var popup = document.getElementById("historyUndoWindowPopup");
  335.   if (popup)
  336.     popup.setAttribute("contextmenu", "tm_undocloseWindowContextMenu");
  337. }
  338.  
  339. // check multi-row status when we get out of fullscreen
  340. eval("FullScreen.mouseoverToggle="+FullScreen.mouseoverToggle.toString().replace(
  341. 'gBrowser.mStrip.setAttribute("moz-collapsed", !aShow);',
  342. 'if (aShow && gHideTabBar != 2) gTMPprefObserver.setTabBarVisibility(true); \
  343.  else $&'
  344. ));
  345.  
  346. if (gisToolbarMode) {
  347.    // after bug 347930 - change Tab strip to be a toolbar
  348.    eval("gBrowser.setStripVisibilityTo ="+gBrowser.setStripVisibilityTo.toString().replace(
  349.      'if (this._toolbar && this.mPrefs.getBoolPref("browser.tabs.autoHide"))',
  350.      'if (this._toolbar && (!aShow || gHideTabBar != 2))'
  351.    ));
  352.  
  353.   // add tabs-toolbar to the toolbar popup list when the tabbar is on the bottom
  354.   eval("onViewToolbarsPopupShowing="+onViewToolbarsPopupShowing.toString().replace(
  355.     /(\})(\)?)$/,
  356.     'TMP_onViewToolbarsPopupShowing(popup, firstMenuItem); \
  357.      $1$2'
  358.   ));
  359.  
  360.   // make sure that tabs-toolbar is on the top before we enter customize toolbar mode
  361.   var _command = document.getElementById("cmd_CustomizeToolbars");
  362.   if (_command)
  363.     _command.setAttribute("oncommand", "TMP_BrowserCustomizeToolbar();" + _command.getAttribute("oncommand"));
  364. }
  365. else {
  366.    eval("gBrowser.setStripVisibilityTo ="+gBrowser.setStripVisibilityTo.toString().replace(
  367.      'this.mStrip.collapsed = !aShow;',
  368.      'if (!aShow || gHideTabBar != 2) $&'
  369.    ));
  370. }
  371.  
  372. /*
  373.  *
  374.  * Fix compatibility with other extensions
  375.  *
  376.  */
  377. // linkification extension
  378. if ("objLinkify" in window && "ClickLink" in objLinkify)
  379. eval("objLinkify.ClickLink ="+objLinkify.ClickLink.toString().replace(
  380. 'if (bOpenWindow)',
  381. 'if (bOpenWindow && !gSingleWindowMode)'
  382. ).replace(
  383. 'if (bOpenTab)',
  384. 'if (bOpenTab || TMP_whereToOpen(null).lock)'
  385. ));
  386.  
  387. // trigger tabmix function when user change tab width with faviconize extension
  388. if ("faviconize" in window && "toggle" in faviconize)
  389. eval("faviconize.toggle = " + faviconize.toggle.toString().replace(
  390. /}$/,
  391. 'tabBarScrollStatus(); checkBeforeAndAfter(); $&'
  392. ));
  393.  
  394. // make ChromaTabs extension compatible with Tabmix Plus
  395. if ("CHROMATABS" in window)
  396. eval("CHROMATABS.colorizeTab ="+CHROMATABS.colorizeTab.toString().replace(
  397. 'node = doc.getAnonymousElementByAttribute(tab, "class", "tab-image-left");',
  398. 'node = doc.getAnonymousElementByAttribute(tab, "class", "tab-image-left tab-startcap tab-left tab-left-border");'
  399. ).replace(
  400. 'node = doc.getAnonymousElementByAttribute(tab, "class", "tab-image-middle");',
  401. 'node = doc.getAnonymousElementByAttribute(tab, "class", "tab-middle box-inherit tab-image-middle tab-body");'
  402. ).replace(
  403. 'node = doc.getAnonymousElementByAttribute(tab, "class", "tab-close-button");',
  404. 'node = doc.getAnonymousElementByAttribute(tab, "anonid", "tmp-close-button");'
  405. ).replace(
  406. 'node = doc.getAnonymousElementByAttribute(tab, "class", "tab-image-right");',
  407. 'node = doc.getAnonymousElementByAttribute(tab, "class", "tab-image-right tab-endcap tab-right tab-right-border");'
  408. ));
  409.  
  410. // fix bug in superDargandGo
  411. try {
  412. if ("superDrag" in window)
  413. eval("contentAreaDNDObserver.onDrop ="+contentAreaDNDObserver.onDrop.toString().replace(
  414. 'document.firstChild.getAttribute("windowtype")',
  415. 'window.document.documentElement.getAttribute("windowtype")'
  416. ).replace(
  417. 'preventBubble()',
  418. 'stopPropagation()'
  419. ));
  420. } catch (ex) {}
  421.  
  422. // make URL Suffix extension compatible with tabmix
  423. if ("objURLsuffix" in window) {
  424.   if ("handleURLBarCommand" in objURLsuffix)
  425.   eval("objURLsuffix.handleURLBarCommand ="+objURLsuffix.handleURLBarCommand.toString().replace(
  426.     'objURLsuffix.BrowserLoadURL(aTriggeringEvent, postData.value, altDisabled);',
  427.     'TMP_BrowserLoadURL(aTriggeringEvent, postData.value, altDisabled);'
  428.   ).replace(
  429.     'objURLsuffix.BrowserLoadURL(aTriggeringEvent, postData.value);',
  430.     'TMP_BrowserLoadURL(aTriggeringEvent, postData.value, true);'
  431.   ));
  432.  
  433.   if ("canonizeUrl" in objURLsuffix)
  434.   eval("objURLsuffix.canonizeUrl ="+objURLsuffix.canonizeUrl.toString().replace(
  435.     'return [gURLBar.value, aPostDataRef];',
  436.     'return [gURLBar.value, aPostDataRef, true];'
  437.   ));
  438.  
  439.   window.handleURLBarCommand = objURLsuffix.handleURLBarCommand;
  440. }
  441.  
  442. if ("TreeStyleTabBrowser" in window) {
  443.   // TreeStyleTabBrowser replace boxObject.x to boxObject.y but we change boxObject.x to boxObject.screenX
  444.   function replaceHorizontalProps(aString) {
  445.     return aString.replace(
  446.       /boxObject\.screenX/g,
  447.       'boxObject[screenPosProp]'
  448.     ).replace(
  449.       '{',
  450.       '{var screenPosProp = gBrowser.treeStyleTab.isVertical ? "screenY" : "screenX" ;'
  451.     )
  452.   }
  453.   if (!TreeStyleTabService.getTreePref('TMP.doNotUpdate.isTabVisible'))
  454.     eval('gBrowser.mTabContainer.isTabVisible = '+
  455.        replaceHorizontalProps(gBrowser.mTabContainer.isTabVisible.toSource()));
  456.  
  457.   eval('gBrowser.mTabContainer.ensureTabIsVisible = '+
  458.       replaceHorizontalProps(gBrowser.mTabContainer.ensureTabIsVisible.toSource().replace()));
  459.   /*
  460.    *  TST have eval to TMP_Bookmark.openGroup
  461.    *  we replace TMP_Bookmark.openGroup with TMP_Places.openGroup at Tabmix 0.3.8.2pre.090830
  462.    *  we also replace call to TreeStyleTabService.openGroupBookmarkBehavior(); 
  463.    *  with aOpenGroupBookmarkBehavior that we pass from  PlacesUIUtils._openTabset
  464.    *  we only call this functiom from browserWindow so we don't need to call it for
  465.    *  other places windows
  466.    */
  467.   eval("TMP_Places.openGroup ="+TMP_Places.openGroup.toString().replace(
  468.     /(function[^\(]*\([^\)]+)(\))/,
  469.     '$1, TSTOpenGroupBookmarkBehavior$2'
  470.   ).replace(
  471.     '{',
  472.     '{if (TSTOpenGroupBookmarkBehavior == null) TSTOpenGroupBookmarkBehavior = TreeStyleTabService.openGroupBookmarkBehavior();'
  473.   ).replace(  
  474.     'index = prevTab._tPos + 1;',
  475.     <![CDATA[
  476.       index = gBrowser.treeStyleTab.getNextSiblingTab(gBrowser.treeStyleTab.getRootTab(prevTab));
  477.       if (tabToSelect == aTab) index = gBrowser.treeStyleTab.getNextSiblingTab(index);
  478.         index = index ? index._tPos : (prevTab._tPos + 1);
  479.     ]]>
  480.   ).replace(
  481.     /(prevTab = aTab;)/,
  482.     <![CDATA[
  483.       $1
  484.       if (tabToSelect == aTab && TSTOpenGroupBookmarkBehavior & TreeStyleTabService.kGROUP_BOOKMARK_SUBTREE) {
  485.         TreeStyleTabService.readyToOpenChildTab(tabToSelect, true, gBrowser.treeStyleTab.getNextSiblingTab(tabToSelect));
  486.       }
  487.     ]]>
  488.   ).replace(
  489.     /(tabBar.nextTab)/,
  490.     <![CDATA[
  491.       if (TSTOpenGroupBookmarkBehavior & TreeStyleTabService.kGROUP_BOOKMARK_SUBTREE)
  492.         TreeStyleTabService.stopToOpenChildTab(tabToSelect);
  493.     $1]]>
  494.   ));
  495.  
  496.   // the hack in tree style tab code is obsolete
  497.   var fn = TMP_openMultipleLinks.toString();
  498.   fn = fn.split("return true;");
  499.   fn[fn.length-2] += "if (!check) { TreeStyleTabService.stopToOpenChildTab(focusedWindow); };\n"
  500.   eval("TMP_openMultipleLinks ="+fn.join("return true;").replace(
  501.     'while (nextEpisode != null)',
  502.     'if (!check) TreeStyleTabService.readyToOpenChildTab(focusedWindow, true); \
  503.      $&'
  504.   ));
  505.  
  506.   eval("TreeStyleTabBrowser.prototype.onTabClick ="+TreeStyleTabBrowser.prototype.onTabClick.toString().replace(
  507.     'var tab = this.getTabFromTabbarEvent(aEvent);',
  508.     '$& \
  509.      if (!tab) return;'
  510.   ));
  511.  
  512.   if("bookmarkMultipleTabs" in window['piro.sakura.ne.jp']) {
  513.     eval("window['piro.sakura.ne.jp'].bookmarkMultipleTabs.addBookmarkTabsFilter ="+window['piro.sakura.ne.jp'].bookmarkMultipleTabs.addBookmarkTabsFilter.toString().replace(
  514.       'return aTab.linkedBrowser.currentURI;',
  515.       'var browser = aTab.linkedBrowser; \
  516.        var uri = browser.currentURI; \
  517.        return {uri: uri, title: TMP_Places.getTabFixedTitle(browser, uri)};'
  518.     ));
  519.   }
  520. }
  521.  
  522. /* fast dial FdUtils*/
  523. if ("FdUtils" in window && FdUtils.whereToOpenLink) {
  524.   eval("FdUtils.whereToOpenLink ="+FdUtils.whereToOpenLink.toString().replace(
  525.     'if (e.ctrlKey)',
  526.     'if (e.ctrlKey || TMP_whereToOpen(null).lock)'
  527.   ));
  528. }
  529.  
  530. // with MR Tech's local install extention
  531. // don't open trober in current tab when tab is locked
  532. // or trober is to diffrent site then the current
  533. if (typeof(Local_Install) == "object")
  534. eval("Local_Install.openThrobber ="+Local_Install.openThrobber.toString().replace(
  535. 'local_common.openURL(local_common.getThrobberURL(), inNewTab);',
  536. 'var url = local_common.getThrobberURL(); \
  537.  local_common.openURL(url, inNewTab ? inNewTab : TMP_checkCurrent(url) == "tab");'
  538. ));
  539.  
  540. // unable to close surce tab after duplicate with FireGestures esextension
  541. if ("FireGestures" in window)
  542. eval("FireGestures._performAction ="+FireGestures._performAction.toString().replace(
  543. 'gBrowser.moveTabTo(newTab, ++orgTab._tPos);',
  544. 'gBrowser.moveTabTo(newTab, orgTab._tPos + 1);'
  545. ));
  546.  
  547. gBrowser.TMP_openTabNext = function _TMP_openTabNext(aTab, aCaller) {
  548.    var blockedCallers = {sss_restoreWindow:true, ct_SSS_undoCloseTab:true, TMP_BrowserOpenTab:true};
  549.    if (aCaller in blockedCallers)
  550.      return;
  551.  
  552.    // the fix in TreeStyleTabBrowser 0.8.2009073102 hacks.js make new tab open in wrong place
  553.    // when tab don't have Child tabs
  554.    if (this.mPrefs.getBoolPref("extensions.tabmix.openTabNext")) {
  555.       this.TMmoveTabTo(aTab, this.mCurrentTab._tPos + this.mTabContainer.nextTab,1);
  556.       if (this.mPrefs.getBoolPref("extensions.tabmix.openTabNextInverse"))
  557.         this.mTabContainer.nextTab++;
  558.    }
  559. }
  560.  
  561. gBrowser.TMmoveTabTo = function _TMmoveTabTo(aTab, aIndex, flag) {
  562.   if ( aTab._tPos == aIndex )
  563.     return aTab;
  564.  
  565.   if(!(flag & 1)) this.mTabContainer.nextTab = 1;
  566.   this._browsers = null; // invalidate cache
  567.   this.mTabFilters.splice(aIndex,0,this.mTabFilters.splice(aTab._tPos, 1)[0]);
  568.   this.mTabListeners.splice(aIndex,0,this.mTabListeners.splice(aTab._tPos, 1)[0]);
  569.  
  570.   var tabCount = this.mTabContainer.childNodes.length;
  571.   var newPos = tabCount - 1 < aIndex ? tabCount - 1 : aIndex;
  572.   var oldPosition = aTab._tPos;
  573.  
  574.   aIndex = aIndex < aTab._tPos ? aIndex: aIndex+1;
  575.   this.mCurrentTab._selected = false;
  576.   // use .item() instead of [] because dragging to the end of the strip goes out of
  577.   // bounds: .item() returns null (so it acts like appendChild), but [] throws
  578.   this.mTabContainer.insertBefore(aTab, this.mTabContainer.childNodes.item(aIndex));
  579.  
  580.   // invalidate cache, because mTabContainer is about to change
  581.   this._browsers = null;
  582.   var i;
  583.   for (i = 0; i < tabCount; i++) {
  584.      this.mTabContainer.childNodes[i]._tPos = i;
  585.      this.mTabContainer.childNodes[i]._selected = false;
  586.   }
  587.   this.mCurrentTab._selected = true;
  588.   var evt = document.createEvent("UIEvents");
  589.   evt.initUIEvent("TabMove", true, false, window, oldPosition);
  590.   aTab.dispatchEvent(evt);
  591.  
  592.   SessionManager.tabMoved(aTab, oldPosition, newPos);
  593.  
  594.   this.mTabContainer.ensureTabIsVisible(aTab._tPos);
  595.  
  596.   return aTab;
  597. }
  598.  
  599. gBrowser.duplicateTab = function tabbrowser_duplicateTab(aTab, aHref, aTabData, disallowSelect) {
  600.   if (aTab.localName != "tab")
  601.     aTab = this.mCurrentTab;
  602.  
  603.   var newTab = null;
  604.   // try to have SessionStore duplicate the given tab
  605.   newTab = this.SSS_duplicateTab(aTab, aHref, aTabData);
  606.  
  607.   if(!newTab && aTabData)
  608.     throw new Error("Tabmix was unable to restore closed tab to new window");
  609.  
  610.   // if SSS_duplicateTab failed fall back to TMP_duplicateTab
  611.   if(!newTab)
  612.     newTab = this.TMP_duplicateTab(aTab, aHref);
  613.  
  614.   content.focus();
  615.   var bgPref = this.mPrefs.getBoolPref("extensions.tabmix.loadDuplicateInBackground");
  616.   var copyToNewWindow = window != aTab.ownerDocument.defaultView;
  617.   if (!disallowSelect && !bgPref) {
  618.     newTab.owner = copyToNewWindow ? null : aTab;
  619.     this.TMP_selectNewForegroundTab(newTab, bgPref, aHref || this.getBrowserForTab(aTab).currentURI.spec, false);
  620.   }
  621.  
  622.   if (!disallowSelect && !copyToNewWindow && this.mPrefs.getBoolPref("extensions.tabmix.openDuplicateNext")) {
  623.     var pos = newTab._tPos > aTab._tPos ? 1 : 0;
  624.     this.TMmoveTabTo(newTab, aTab._tPos+pos);
  625.   }
  626.  
  627.   return newTab;
  628. }
  629.  
  630. gBrowser.SSS_duplicateTab = function tabbrowser_SSS_duplicateTab(aTab, aHref, aTabData) {
  631.   var newTab = null;
  632.   try {
  633.     var newTab, tabState;
  634.     // add new history entry after current index, and removing forword history
  635.     function addNewHistoryEntry() {
  636.       var activeIndex = (tabState.index || tabState.entries.length) - 1;
  637.       var entriesToRemove = tabState.entries.length - tabState.index;
  638.       var newEntry = { url: aHref }; // we don't know the page title at this moment
  639.       tabState.entries.splice(activeIndex + 1 , entriesToRemove, newEntry);
  640.       tabState.index++;
  641.     }
  642.     // we need to update history title after the new page loaded for use in back/forword button
  643.     var self = this;
  644.     function updateNewHistoryTitle(aEvent) {
  645.       this.removeEventListener("load", updateNewHistoryTitle, true);
  646.       var history = this.webNavigation.sessionHistory;
  647.       var shEntry = history.getEntryAtIndex(history.index, false).QueryInterface(Ci.nsISHEntry);
  648.       shEntry.setTitle(self.getTabForBrowser(this).label);
  649.     }
  650.  
  651.     var ss = Cc["@mozilla.org/browser/sessionstore;1"]
  652.                    .getService(Ci.nsISessionStore);
  653.     tabState = aTabData ? aTabData.state : eval("(" + ss.getTabState(aTab) + ")");
  654.     TMP_SessionStore.removeWyciwyg(tabState);
  655.     newTab = this.addTab("about:blank");
  656.     if (aHref) {
  657.       addNewHistoryEntry();
  658.       this.getBrowserForTab(newTab).addEventListener("load", updateNewHistoryTitle, true);
  659.     }
  660.     ss.setTabState(newTab, tabState.toSource());
  661.   } catch (ex) {TMP_ASSERT(ex);}
  662.  
  663.   return newTab;
  664. }
  665.  
  666. gBrowser.TMP_duplicateTab = function tabbrowser_TMP_duplicateTab(aTab, href) {
  667. try {
  668.   var aBrowser = this.getBrowserForTab(aTab);
  669.   var originalHistory = aBrowser.webNavigation.sessionHistory;
  670.   var newTab = this.addTab("about:blank");
  671.  
  672.   var newBrowser = this.getBrowserForTab(newTab);
  673.   var prop = SessionData.getTabProperties(aTab);
  674.   SessionData.setTabProperties(newTab, prop);
  675.  
  676.   newBrowser.addEventListener('load', dupScrollPosition, true);
  677.   //save scroll data and href to load after we clone tab history
  678.   var bContent = aBrowser.contentWindow;
  679.   newBrowser._scrollData = {
  680.       href: href,
  681.       _scrollX: bContent.scrollX,
  682.       _scrollY: bContent.scrollY
  683.   };
  684.  
  685.   dtMergeWindows.cloneTabHistory(newBrowser.webNavigation, dtMergeWindows.copyHistory(originalHistory));
  686. } catch (ex) {TMP_ASSERT(ex);}
  687.   return newTab;
  688.  
  689. }
  690.  
  691. gBrowser.duplicateInWindow = function (aTab, aMoveTab, aTabData) {
  692.   if (aTab.localName != "tab")
  693.     aTab = this.mCurrentTab;
  694.  
  695.   if (gSingleWindowMode) {
  696.     if (!aMoveTab)
  697.       this.duplicateTab(aTab, null, aTabData);
  698.  
  699.     return;
  700.   }
  701.  
  702.   if (gIsFirefox35 && aMoveTab) {
  703.     this.replaceTabWithWindow(aTab);
  704.     return;
  705.   }
  706.  
  707.   function _restoreWindow(aWindow, aCount) {
  708.     // use getBrowser() for Firefox 3.0
  709.     var tabBrowser = aWindow.getBrowser();
  710.     // make sure sessionHistory is ready
  711.     try {
  712.       if (!tabBrowser.webNavigation.sessionHistory) {
  713.         throw new Error();
  714.       }
  715.     }
  716.     catch (ex) { // in case browser or history aren't ready yet
  717.       if (aCount < 10) {
  718.         var restoreHistoryFunc = function() {_restoreWindow(aWindow, aCount + 1); }
  719.         aWindow.setTimeout(restoreHistoryFunc, 100);
  720.         return;
  721.       }
  722.     }
  723.  
  724.     var oldTab = aWindow._duplicateData.tab;
  725.     var tabData = aWindow._duplicateData.tabData;
  726.     var sourceWindow = aWindow.opener;
  727.     // we don't have to do anything if the openr not exist, or we copy only tabdata
  728.     var moveMode = aWindow._duplicateData.move && sourceWindow && !tabData;
  729.     if (moveMode) {
  730.       var sourceBrowser = sourceWindow.gBrowser;
  731.     }
  732.     // remove unused blank tab
  733.     var blankTabToRemove = null;
  734.     if (tabBrowser.isBlankNotBusyTab(tabBrowser.mCurrentTab)) {
  735.       blankTabToRemove = tabBrowser.mCurrentTab;
  736.       blankTabToRemove.collapsed = true;
  737.     }
  738.     var newTab = tabBrowser.duplicateTab(oldTab, null, tabData);
  739.     if (blankTabToRemove)
  740.       tabBrowser.removeTab(blankTabToRemove);
  741.  
  742.     // make sure the new tab is in the end
  743.     var lastIndex = tabBrowser.mTabContainer.childNodes.length - 1;
  744.     if (newTab._tPos < lastIndex)
  745.       tabBrowser.moveTabTo(newTab, lastIndex);
  746.  
  747.     // remove old tab and close the other window if _duplicateTab was its last tab
  748.     if (moveMode) {
  749.       var needToClose = "needToClose" in  sourceWindow;
  750.       if (oldTab.parentNode) { // make sure the tab still exist before we try to remove it
  751.         needToClose = needToClose || sourceBrowser.mTabContainer.childNodes.length == 1;
  752.         oldTab.removeAttribute("protected");
  753.         sourceBrowser.removeTab(oldTab);
  754.       }
  755.  
  756.       if (needToClose)
  757.         sourceWindow.closeWindow(true);
  758.     }
  759.  
  760.     delete newWindow._duplicateData;
  761.   }
  762.  
  763.   // we going to delete the moved tab after some timeout catch the flag now
  764.   // we use this only if the tab was not exist anymore when its time to remove it
  765.   if (aMoveTab && this.mTabContainer.childNodes.length == 1)
  766.     window.needToClose = true;
  767.  
  768.   // open new window
  769.   var newWindow = window.openDialog( getBrowserURL(), "_blank", "chrome,all,dialog=no");
  770.   newWindow.tabmix_afterTabduplicated = true;
  771.   newWindow._duplicateData = {tab: aTab, tabData: aTabData, move: aMoveTab};
  772.   newWindow.addEventListener("load", function (aEvent) {
  773.       var win = aEvent.currentTarget;
  774.       win.removeEventListener("load", arguments.callee, false);
  775.       // make sure sessionstore is init
  776.       try {
  777.         var ss = Cc["@mozilla.org/browser/sessionstore;1"].
  778.                  getService(Ci.nsISessionStore);
  779.         ss.init(win);
  780.       } catch(ex) {
  781.         dump("nsSessionStore could not be initialized: " + ex + "\n");
  782.         return;
  783.       }
  784.       _restoreWindow(win, 0);
  785.   }, false);
  786.  
  787. }
  788.  
  789. gBrowser.openLinkWithHistory = function (aTab) {
  790.   var url = gContextMenu.linkURL;
  791.   if (!isValidUrl(url))
  792.      url = null;
  793.  
  794.   var newTab = this.duplicateTab(aTab, url, null, url == null);
  795.  
  796.   if (!url) {
  797.     try {
  798.       // flip aTab with newTab
  799.       // and dispatch click event on the link....
  800.       newTab.removeAttribute("busy");
  801.       this.setIcon(newTab, this.getBrowserForTab(aTab).mIconURL);
  802.       newTab.label = aTab.label;
  803.       newTab.width = aTab.width;
  804.  
  805.       var index = newTab._tPos;
  806.       this.TMmoveTabTo(newTab, aTab._tPos);
  807.       var pos = index > aTab._tPos ? 1 : 0;
  808.       this.TMmoveTabTo(aTab, index + pos);
  809.  
  810.       if (this.mPrefs.getBoolPref("extensions.tabmix.loadDuplicateInBackground")) {
  811.         this.selectedTab = newTab;
  812.         aTab.removeAttribute("visited");
  813.         aTab.removeAttribute("flst_id");
  814.       }
  815.       else {
  816.         aTab.owner = newTab;
  817.         this.selectedTab = aTab;
  818.         newTab.setAttribute("flst_id", new Date().getTime());
  819.         newTab.setAttribute("visited", true);
  820.         newTab.setAttribute("dontremovevisited", true);
  821.         aTab.setAttribute("flst_id", new Date().getTime());
  822.       }
  823.  
  824.       var event = document.createEvent("Events");
  825.       event.initEvent("click", true, true);
  826.       event.getPreventDefault = function () { return false; }
  827.       gContextMenu.target.dispatchEvent(event);
  828.  
  829.       newTab = aTab;
  830.     }
  831.     catch (ex) {TMP_ASSERT(ex);}
  832.   }
  833.  
  834.   return newTab;
  835. }
  836.  
  837. gBrowser.openHereWith = function () {
  838.   var url = gContextMenu.linkURL;
  839.   if (!isValidUrl(url))
  840.      return;
  841.  
  842.   openUILinkIn(gContextMenu.linkURL, "current", null, null, gContextMenu.target.ownerDocument.documentURIObject);
  843. }
  844.  
  845. gBrowser.openInverseLink = function () {
  846.   var url = gContextMenu.linkURL;
  847.   if (!isValidUrl(url))
  848.      return null;
  849.  
  850.   // aTab is for treeStyleTab extension look in treeStyleTab hacks.js
  851.   var aTab = this.selectedTab;
  852.  
  853.   var bgPref = this.mPrefs.getBoolPref("browser.tabs.loadInBackground");
  854.   var newTab = this.loadOneTab(url, null, null, null, !bgPref, true);
  855.   if (url == "about:blank")
  856.     setURLBarFocus();
  857.   return newTab;
  858. }
  859.  
  860. window.isValidUrl = function (aUrl) {
  861.   // valid urls don't contain spaces ' '; if we have a space it isn't a valid url.
  862.   // Also disallow dropping javascript: or data: urls--bail out
  863.   if (!aUrl || !aUrl.length || aUrl.indexOf(" ", 0) != -1 ||
  864.        /^\s*(javascript|data):/.test(aUrl))
  865.     return false;
  866.  
  867.   return true;
  868. }
  869.  
  870. gBrowser.closeAllTabs = function TMP_closeAllTabs() {
  871.    if (this.warnAboutClosingTabs("All")) {
  872.       var childNodes = this.mTabContainer.childNodes;
  873.       if (this.mTabContainer.collapsedTabs > 0)
  874.          this.mTabContainer.collapsedTabs = 0;
  875.  
  876.       for (var i = childNodes.length - 1; i >= 0; --i) {
  877.          if (childNodes[i] != this.mCurrentTab)
  878.             this.removeTab(childNodes[i], true);
  879.       }
  880.       this.removeTab(this.mCurrentTab, true);
  881.       // _handleTabSelect will call ensureTabIsVisible
  882.    }
  883. }
  884.  
  885. gBrowser.closeGroupTabs = function TMP_closeGroupTabs(aTab) {
  886.    if (aTab.localName != "tab")
  887.       aTab = this.mCurrentTab;
  888.  
  889.    var URL = this.getBrowserForTab(aTab).currentURI.spec;
  890.    var matches = URL.match(/(^.*\/)(.*)/);
  891.    var aDomain = matches ?  matches[1] : URL;
  892.  
  893.    if (this.warnAboutClosingTabs("Group", null, null, aDomain)) {
  894.       var childNodes = this.mTabContainer.childNodes;
  895.       if (this.mTabContainer.collapsedTabs > 0)
  896.          this.mTabContainer.collapsedTabs = 0;
  897.       for (var i = childNodes.length - 1; i > -1; --i) {
  898.          if (childNodes[i] != aTab &&
  899.                this.getBrowserForTab(childNodes[i]).currentURI.spec.indexOf(aDomain) != -1)
  900.             this.removeTab(childNodes[i], true);
  901.       }
  902.       this.removeTab(aTab, true);
  903.       this.mTabContainer.ensureTabIsVisible(this.mTabContainer.selectedIndex);
  904.    }
  905. }
  906.  
  907. gBrowser.closeRightTabs = function (aTab) {
  908.    if (aTab.localName != "tab")
  909.       aTab = this.mCurrentTab;
  910.  
  911.    if (this.warnAboutClosingTabs("Right", aTab._tPos)) {
  912.       if ( aTab._tPos < this.mCurrentTab._tPos )
  913.          this.mTabContainer.selectedItem = aTab;
  914.  
  915.       var childNodes = this.mTabContainer.childNodes;
  916.       for (var i = childNodes.length - 1; i > aTab._tPos; i-- )
  917.          this.removeTab(childNodes[i], true);
  918.    }
  919. }
  920.  
  921. gBrowser.closeLeftTabs = function TMP_closeLeftTabs(aTab) {
  922.    if (aTab.localName != "tab")
  923.       aTab = this.mCurrentTab;
  924.  
  925.    if (this.warnAboutClosingTabs("Left", aTab._tPos)) {
  926.       if ( aTab._tPos > this.mCurrentTab._tPos ) {
  927.          this.mTabContainer.selectedItem = aTab;
  928.       }
  929.       this.mTabContainer.ensureTabIsVisible(this.mTabContainer.selectedIndex);
  930.  
  931.       var childNodes = this.mTabContainer.childNodes;
  932.       if (this.mTabContainer.collapsedTabs > 0)
  933.          this.mTabContainer.collapsedTabs = 0;
  934.       for (var i = aTab._tPos - 1; i >= 0; i-- )
  935.          this.removeTab(childNodes[i], true);
  936.    }
  937. }
  938.  
  939. gBrowser.removeAllTabsBut = function TMP_removeAllTabsBut(aTab) {
  940.    if (aTab.localName != "tab")
  941.       aTab = this.mCurrentTab;
  942.  
  943.    if (this.warnAboutClosingTabs("AllBut", null, aTab.hasAttribute("protected"))) {
  944.       if (aTab != this.mCurrentTab) {
  945.          this.mTabContainer.selectedItem = aTab;
  946.       }
  947.       this.mTabContainer.ensureTabIsVisible(this.mTabContainer.selectedIndex);
  948.       var childNodes = this.mTabContainer.childNodes;
  949.       if (this.mTabContainer.collapsedTabs > 0)
  950.          this.mTabContainer.collapsedTabs = 0;
  951.       for (var i = childNodes.length - 1; i >= 0; --i) {
  952.          if (childNodes[i] != aTab)
  953.             this.removeTab(childNodes[i], true);
  954.       }
  955.    }
  956. }
  957.  
  958. gBrowser.reloadLeftTabs = function (aTab) {
  959.   if (aTab.localName != "tab")
  960.     aTab = this.mCurrentTab;
  961.   var childNodes = this.mTabContainer.childNodes;
  962.   if ( aTab._tPos > this.mCurrentTab._tPos )
  963.     this.mTabContainer.selectedItem = aTab;
  964.   for (var i = aTab._tPos - 1; i >= 0; i-- ) {
  965.     try {
  966.       this.getBrowserForTab(childNodes[i]).reload();
  967.     } catch (e) {  }
  968.   }
  969. }
  970.  
  971. gBrowser.reloadRightTabs = function (aTab) {
  972.   if (aTab.localName != "tab")
  973.     aTab = this.mCurrentTab;
  974.   var childNodes = this.mTabContainer.childNodes;
  975.   if ( aTab._tPos < this.mCurrentTab._tPos )
  976.     this.mTabContainer.selectedItem = aTab;
  977.   for (var i = childNodes.length - 1; i > aTab._tPos; i-- ) {
  978.     try {
  979.       this.getBrowserForTab(childNodes[i]).reload();
  980.     } catch (e) {  }
  981.   }
  982. }
  983.  
  984. gBrowser.reloadAllTabsBut = function (aTab) {
  985.   if (aTab.localName != "tab")
  986.     aTab = this.mCurrentTab;
  987.   else
  988.     this.mTabContainer.selectedItem = aTab;
  989.   var childNodes = this.mTabContainer.childNodes;
  990.   for (var i = childNodes.length - 1; i >= 0; --i) {
  991.     if (childNodes[i] == aTab)
  992.        continue;
  993.     try {
  994.       this.getBrowserForTab(childNodes[i]).reload();
  995.     } catch (e) {  }
  996.   }
  997. }
  998.  
  999. // we keep this function to saty compatible with other extensions that use it
  1000. gBrowser.undoRemoveTab = function () {
  1001.    TMP_ClosedTabs.undoCloseTab();
  1002. }
  1003.  
  1004. gBrowser.delayUndoRemoveAllTab = function () {
  1005.    // call undoRemoveAllTab after delay to let the popup menu time to hide
  1006.    var _this = this;
  1007.    window.setTimeout( function () { _this.undoRemoveAllTab(); }, 0 );
  1008. }
  1009.  
  1010. gBrowser.undoRemoveAllTab = function () {
  1011.   if (!PlacesController.prototype._confirmOpenTabs(this.closedTabs.length))
  1012.     return;
  1013.  
  1014.   var aTab, blankTab, newTab, selectTab = true;
  1015.   // catch blank tab for reuse
  1016.   var blankTabs = [];
  1017.   for (var i = 0; i < this.mTabs.length ; i++) {
  1018.     aTab = this.mTabs[i];
  1019.     if (this.isBlankNotBusyTab(aTab)) {
  1020.       aTab.reuse = true;
  1021.       blankTabs.push(aTab);
  1022.     }
  1023.   }
  1024.  
  1025.   while (this.closedTabs.length > 0) {
  1026.     aTab = getClosedTab("original", 0);
  1027.     blankTab = blankTabs.pop();
  1028.     newTab = (blankTab) ? blankTab : this.addTab("about:blank");
  1029.  
  1030.     this.restoreTabData(newTab, aTab.pos, aTab.history, aTab.properties, aTab.scroll, selectTab);
  1031.     selectTab = false;
  1032.  
  1033.     // for TreeStyleTab extension
  1034.     if ("TreeStyleTabBrowser" in window && this.treeStyleTab && this.treeStyleTab.useTMPSessionAPI)
  1035.        this.treeStyleTab.onTabRestored({ target : newTab, originalTarget : newTab });
  1036.  
  1037.   }
  1038.  
  1039.   // remove unused blank tabs
  1040.   while(blankTabs.length > 0){
  1041.     blankTab = blankTabs.pop();
  1042.     this.removeTab(blankTab);
  1043.   }
  1044.  
  1045.   this.mTabContainer.nextTab = 1
  1046. }
  1047.  
  1048. gBrowser.restoreTab = function tabbrowser_restoreTab(ord, hist, prop, zoom) {
  1049.   // reuse blanke tab
  1050.   var newTab = this.selectedTab;
  1051.   if (!newTab.parentNode || !this.isBlankNotBusyTab(newTab))
  1052.     newTab = this.addTab("about:blank");
  1053.  
  1054.   this.restoreTabData(newTab, ord, hist, prop, zoom, true);
  1055.   return newTab;
  1056. }
  1057.  
  1058. gBrowser.restoreTabData = function tabbrowser_restoreTabData(newTab, ord, hist, prop, zoom, selectTab) {
  1059.   var newBrowser = this.getBrowserForTab(newTab);
  1060.   var restorePosition = this.mPrefs.getBoolPref("extensions.tabmix.undoClosePosition");
  1061.   var newPos;
  1062.   var lastIndex = this.mTabContainer.childNodes.length - 1;
  1063.   if ( restorePosition ) {
  1064.     newPos = ord > lastIndex ? lastIndex : ord;
  1065.     this.TMmoveTabTo(newTab, newPos);
  1066.   }
  1067.   else if (newTab.reuse) {
  1068.     // move reuse tabs to the end when restore all closed tabs list
  1069.     var openTabNext = this.mPrefs.getBoolPref("extensions.tabmix.openTabNext");
  1070.     newPos = openTabNext ? this.mCurrentTab._tPos + this.mTabContainer.nextTab++ : lastIndex;
  1071.     this.TMmoveTabTo(newTab, newPos, 1);
  1072.     if (newTab != this.mCurrentTab)
  1073.       newTab.removeAttribute("flst_id");
  1074.     delete newTab.reuse;
  1075.   }
  1076.  
  1077.   SessionData.setTabProperties(newTab, prop);
  1078.  
  1079.   var oldHistory = hist;
  1080.   var newHistory = newBrowser.webNavigation.sessionHistory;
  1081.   // reset old history
  1082.   if (newHistory.count > 0) {
  1083.     newHistory.PurgeHistory(newHistory.count);
  1084.   }
  1085.  
  1086.   newHistory.QueryInterface(Components.interfaces.nsISHistoryInternal);
  1087.   for (var i = 0; i < oldHistory.count; i++) {
  1088.     newHistory.addEntry(oldHistory.getEntryAtIndex(i, false), true);
  1089.   }
  1090.   if( oldHistory.count ) {
  1091.     try { newBrowser.webNavigation.gotoIndex(oldHistory.index); } catch (e) {}
  1092.   }
  1093.  
  1094.   // call to set scroll Position for restored closed tab from prev session
  1095.   if (zoom && zoom != "0,0,1") {
  1096.      newBrowser.addEventListener('load', dupScrollPosition, true);
  1097.      newBrowser._scrollData = {
  1098.        href: null,
  1099.        _scrollX: XYZ[0],
  1100.        _scrollY: XYZ[1]
  1101.      }
  1102.   }
  1103.  
  1104.   if (selectTab) {
  1105.     this.selectedTab = newTab;
  1106.     // focus the tab's content area
  1107.     setTimeout(function(_content) { _content.focus(); }, 0, newBrowser.contentWindow);
  1108.   }
  1109.  
  1110.   return newTab;
  1111. }
  1112.  
  1113. gBrowser.lockTab = function (aTab) {
  1114.   if (aTab.localName != "tab")
  1115.     aTab = this.mCurrentTab;
  1116.   if ( aTab.hasAttribute("locked") ) {
  1117.     aTab.removeAttribute("locked");
  1118.     aTab.setAttribute("_locked", "false");
  1119.   }
  1120.   else {
  1121.     aTab.setAttribute("locked", "true");
  1122.     aTab.setAttribute("_locked", "true");
  1123.   }
  1124.   SessionManager.updateTabProp(aTab);
  1125. }
  1126.  
  1127. gBrowser.protectTab = function (aTab) {
  1128.   if (aTab.localName != "tab")
  1129.     aTab = this.mCurrentTab;
  1130.   if ( aTab.hasAttribute("protected") )
  1131.     aTab.removeAttribute("protected");
  1132.   else
  1133.     aTab.setAttribute("protected", "true");
  1134.   SessionManager.updateTabProp(aTab);
  1135. }
  1136.  
  1137. gBrowser.freezeTab = function (aTab) {
  1138.   if (aTab.localName != "tab")
  1139.     aTab = this.mCurrentTab;
  1140.   if ( !aTab.hasAttribute("protected") || !aTab.hasAttribute("locked")){
  1141.     aTab.setAttribute("protected", "true");
  1142.     aTab.setAttribute("locked", "true");
  1143.     aTab.setAttribute("_locked", "true");
  1144.   } else {
  1145.     aTab.removeAttribute("protected");
  1146.     aTab.removeAttribute("locked");
  1147.     aTab.setAttribute("_locked", "false");
  1148.   }
  1149.   SessionManager.updateTabProp(aTab);
  1150. }
  1151.  
  1152. gBrowser.SelectToMerge = function(aTab) {
  1153.   if (gSingleWindowMode && numberOfWindows() == 1) return;
  1154.   if (aTab.localName != "tab")
  1155.     aTab = this.mCurrentTab;
  1156.   if (aTab.hasAttribute("mergeselected")) {
  1157.     aTab.removeAttribute("mergeselected");
  1158.     aTab.label = aTab.label.substr(4);
  1159.   } else {
  1160.     aTab.setAttribute("mergeselected", "true")
  1161.     aTab.label = "(*) "+aTab.label;
  1162.   }
  1163.   if (gWidthFitTitle) {
  1164.     tabBarScrollStatus();
  1165.     checkBeforeAndAfter();
  1166.   }
  1167. }
  1168.  
  1169. gBrowser.onSetReloadTime = function(aTab, aReloadTime) {
  1170.   if (aTab.localName != "tab")
  1171.     aTab = this.mCurrentTab;
  1172.   aTab.autoReloadTime = aReloadTime;
  1173.   this.mPrefs.setIntPref("extensions.tabmix.reload_time", aTab.autoReloadTime);
  1174.   this.enableAutoReload(aTab);
  1175. }
  1176.  
  1177. gBrowser.onAutoReloadEnable = function (aTab) {
  1178.   if (aTab.localName != "tab")
  1179.     aTab = this.mCurrentTab;
  1180.   if (aTab.autoReloadEnabled)
  1181.     this.disableAutoReload(aTab);
  1182.   else
  1183.     this.enableAutoReload(aTab);
  1184. }
  1185.  
  1186. gBrowser.enableAutoReload = function(aTab) {
  1187.   var url = this.getBrowserForTab(aTab).currentURI.spec
  1188.   if (url.match(/^about:/))
  1189.     return;
  1190.   aTab.autoReloadEnabled = true;
  1191.   aTab.autoReloadURI = url;
  1192.   clearTimeout(aTab.autoReloadTimerID);
  1193.   aTab.autoReloadTimerID = setTimeout(reloadPage, aTab.autoReloadTime*1000, aTab);
  1194.   aTab.setAttribute("reload-data", aTab.autoReloadURI + " " + aTab.autoReloadTime);
  1195. }
  1196.  
  1197. gBrowser.disableAutoReload = function (aTab) {
  1198.   aTab.autoReloadEnabled = false;
  1199.   aTab.autoReloadURI = null;
  1200.   aTab.postDataAcceptedByUser = false;
  1201.   clearTimeout(aTab.autoReloadTimerID);
  1202.   aTab.removeAttribute("reload-data");
  1203. }
  1204.  
  1205. gBrowser.onEnableAutoReloadAllTabs = function () {
  1206.   var tabs = this.mTabContainer.childNodes;
  1207.   for(var i=0; i<tabs.length; i++){
  1208.     var tab = tabs[i];
  1209.     if (tab.autoReloadEnabled == null)
  1210.       setupAutoReload(tab);
  1211.  
  1212.     if (!tab.autoReloadEnabled || tab.autoReloadURI != this.getBrowserForTab(tab).currentURI.spec)
  1213.       this.enableAutoReload(tab);
  1214.   }
  1215. }
  1216.  
  1217. gBrowser.onDisableAutoReloadAllTabs = function () {
  1218.   var tabs = this.mTabContainer.childNodes;
  1219.   for(var i=0; i<tabs.length; i++){
  1220.     var tab = tabs[i];
  1221.     if (tab.autoReloadEnabled)
  1222.       this.disableAutoReload(tab);
  1223.   }
  1224. }
  1225.  
  1226. gBrowser.onAutoReloadCustom = function(aTab) {
  1227.   if (aTab.localName != "tab")
  1228.     aTab = this.mCurrentTab;
  1229.   window.openDialog('chrome://tabmixplus/content/minit/autoReload.xul', '_blank', 'chrome,modal,centerscreen', autoReloadDialogResult);
  1230.   if (gAutoReloadDialogAccepted) {
  1231.     aTab.autoReloadTime = this.mPrefs.getIntPref("extensions.tabmix.custom_reload_time");
  1232.     this.enableAutoReload(aTab);
  1233.   }
  1234. }
  1235.  
  1236. gBrowser.onTabReloaded = function(aTab, aBrowser) {
  1237.   if (aTab.autoReloadTimerID)
  1238.     clearTimeout(aTab.autoReloadTimerID);
  1239.  
  1240.   if (aTab.autoReloadURI == aBrowser.currentURI.spec) {
  1241.     if (aBrowser.curScrollX || aBrowser.curScrollY)
  1242.       aBrowser.contentWindow.scrollTo(aBrowser.curScrollX, aBrowser.curScrollY);
  1243.  
  1244.     if (!aTab.autoReloadEnabled)
  1245.       aTab.autoReloadEnabled = true;
  1246.  
  1247.     aTab.autoReloadTimerID = setTimeout(reloadPage, aTab.autoReloadTime*1000, aTab);
  1248.   }
  1249.   else if (aTab.autoReloadEnabled)
  1250.     aTab.autoReloadEnabled = false;
  1251. }
  1252.  
  1253. gBrowser.copyTabUrl = function (aTab) {
  1254.   if (aTab.localName != "tab")
  1255.     aTab = this.mCurrentTab;
  1256.   var URL = this.getBrowserForTab(aTab).contentDocument.location;
  1257.  
  1258.   var clipboard = Components.classes["@mozilla.org/widget/clipboardhelper;1"]
  1259.                    .getService(Components.interfaces.nsIClipboardHelper);
  1260.  
  1261.   clipboard.copyString(URL);
  1262. }
  1263.  
  1264. gBrowser.renameTab = function(aTab) {
  1265.    if (aTab.localName != "tab") aTab = this.mCurrentTab;
  1266.    var browser = this.getBrowserForTab(aTab);
  1267.    var url = browser.contentDocument.baseURI || browser.currentURI.spec;
  1268.    var docTitle = getTitleFromBookmark(url, browser.contentDocument.title, aTab.getAttribute("tabmix_bookmarkId"))
  1269.                             || this.mStringBundle.getString("tabs.untitled");
  1270.    var tabTitle;
  1271.    if (aTab.getAttribute("label-uri") == url || aTab.getAttribute("label-uri") == "*")
  1272.       tabTitle = aTab.getAttribute("fixed-label");
  1273.    else
  1274.       tabTitle = docTitle;
  1275.  
  1276.    var data = {
  1277.       value: tabTitle,
  1278.       rename_all: this._renameAll != null ? this._renameAll : this.mPrefs.getBoolPref("extensions.tabmix.titlefrombookmark"),
  1279.       permanently: aTab.getAttribute("label-uri") == "*",
  1280.       resetTitle: false,
  1281.       modified: false,
  1282.       docTitle: docTitle
  1283.    };
  1284.    window.openDialog('chrome://tabmixplus/content/minit/setFixedLabel.xul', '_blank', 'chrome,modal,centerscreen', data);
  1285.    this._renameAll = data.rename_all;
  1286.    if (data.modified) {
  1287.       var label = data.value;
  1288.       if (data.rename_all)
  1289.          this.setFixLabel(label, url, !data.resetTitle && data.value != docTitle);
  1290.       else {
  1291.          var resetDefault = data.resetTitle || (data.value == docTitle && !data.permanently);
  1292.          TMP_setItem(aTab, "fixed-label", resetDefault ? null : label);
  1293.          var _url = resetDefault ? null : data.permanently ? "*" : url;
  1294.          TMP_setItem(aTab, "label-uri", _url);
  1295.          SessionManager.updateTabProp(aTab);
  1296.          if (aTab.getAttribute('label') != label) {
  1297.             aTab.setAttribute('label', label);
  1298.             if (gWidthFitTitle) {
  1299.               tabBarScrollStatus();
  1300.               checkBeforeAndAfter();
  1301.             }
  1302.             if (aTab == this.mCurrentTab)
  1303.                this.updateTitlebar();
  1304.          }
  1305.       }
  1306.    }
  1307. }
  1308.  
  1309. gBrowser.setFixLabel = function (label, url, setFixedLabel) {
  1310.    // if setFixedLabel is false we reset title to default
  1311.    var i, wnd, aTab, browser, enumerator = windowEnumerator(), titleChanged = false;
  1312.    while (enumerator.hasMoreElements()) {
  1313.       wnd = enumerator.getNext();
  1314.       for (i = 0; i < wnd.gBrowser.mTabs.length; i++) {
  1315.          aTab = wnd.gBrowser.mTabs[i];
  1316.          browser = wnd.gBrowser.getBrowserForTab(aTab);
  1317.          if (browser.currentURI.spec == url) {
  1318.             wnd.TMP_setItem(aTab, "fixed-label", setFixedLabel ? label : null);
  1319.             wnd.TMP_setItem(aTab, "label-uri", setFixedLabel ? url : null);
  1320.             wnd.SessionManager.updateTabProp(aTab);
  1321.             if (aTab.getAttribute('label') != label) {
  1322.                titleChanged = true;
  1323.                aTab.setAttribute('label', label);
  1324.                if (aTab == wnd.gBrowser.mCurrentTab)
  1325.                   wnd.gBrowser.updateTitlebar();
  1326.             }
  1327.          }
  1328.       }
  1329.       if (titleChanged && gWidthFitTitle) {
  1330.          wnd.tabBarScrollStatus();
  1331.          wnd.checkBeforeAndAfter();
  1332.       }
  1333.    }
  1334. }
  1335.  
  1336. gBrowser.previousTabIndex = function _previousTabIndex(aTab) {
  1337.   var temp_id, tempIndex = -1, max_id = 0;
  1338.   var items =  this.mTabContainer.getElementsByAttribute("flst_id", "*");
  1339.   for (var i = 0; i < items.length; ++i ) {
  1340.     temp_id = items[i].getAttribute("flst_id");
  1341.     if (aTab && items[i] == aTab)
  1342.       continue;
  1343.     if ( temp_id && temp_id > max_id ) {
  1344.       max_id = temp_id;
  1345.       tempIndex = items[i]._tPos;
  1346.     }
  1347.   }
  1348.  
  1349.   return tempIndex;
  1350. }
  1351.  
  1352. gBrowser.previousTab = function (aTab) {
  1353.   if (this.mTabs.length == 1) return;
  1354.   var tempIndex = this.previousTabIndex(aTab);
  1355.  
  1356.   // if no flst_id go to previousTab tab, from first tab go to the next tab
  1357.   if (tempIndex == -1)
  1358.     tempIndex = aTab._tPos == 0 ? 1 : aTab._tPos - 1;
  1359.  
  1360.   this.selectedTab = this.mTabs[tempIndex];
  1361.   if (gIsFirefox36)
  1362.     this.selectedBrowser.focus();
  1363.   else
  1364.     focusElement(content);
  1365. }
  1366.  
  1367. gBrowser.selectIndexAfterRemove = function (oldTab) {
  1368.    var currentIndex = this.mCurrentTab._tPos;
  1369.    if (this.mCurrentTab != oldTab)
  1370.      return currentIndex;
  1371.    var l = this.mTabs.length;
  1372.    if (l==1)
  1373.      return 0;
  1374.    var mode = this.mPrefs.getIntPref("extensions.tabmix.focusTab");
  1375.    switch ( mode ) {
  1376.       case 0: // first tab
  1377.             return currentIndex == 0 ? 1 : 0;
  1378.          break;
  1379.       case 1: // left tab
  1380.             return currentIndex == 0 ? 1 : currentIndex-1 ;
  1381.          break;
  1382.       case 3: // last tab
  1383.             return currentIndex == l - 1 ? currentIndex - 1 : l - 1;
  1384.          break;
  1385.       case 6: // last opened
  1386.             var lastTab = this.getTabForLastPanel();
  1387.             if (lastTab == oldTab && l > 1) {
  1388.               lastTab = document.getAnonymousElementByAttribute(this, "linkedpanel",
  1389.                                     this.mPanelContainer.childNodes[l-2].id);
  1390.             }
  1391.             return lastTab._tPos;
  1392.       case 4: // last selected
  1393.             var tempIndex = this.previousTabIndex(oldTab);
  1394.             // if we don't find last selected we fall back to default
  1395.             if (tempIndex > -1)
  1396.                return tempIndex;
  1397.       case 2: // opener / right  (default )
  1398.       case 5: // right tab
  1399.       default:
  1400.             if (mode != 5 && this.mPrefs.getBoolPref("browser.tabs.selectOwnerOnClose") && "owner" in oldTab) {
  1401.                var owner = oldTab.owner;
  1402.                if (owner && owner.parentNode && owner != oldTab)
  1403.                  // oldTab and owner still exist just return its position
  1404.                  return owner._tPos;
  1405.             }
  1406.    }
  1407.    return currentIndex == l - 1 ? currentIndex - 1 : currentIndex + 1;
  1408. }
  1409.  
  1410. gBrowser.closeTab = function(aTab) {
  1411.    // throws exception when rapid click on close tab button
  1412.    // we call this after delay
  1413.    if (!aTab.parentNode) return;
  1414.    if (this.mTabContainer.childNodes.length == 1 && this.isBlankNotBusyTab(aTab) &&
  1415.       !this.mPrefs.getBoolPref("extensions.tabmix.keepLastTab")) {
  1416.          var urlBar = document.getElementById("urlbar");
  1417.          if (urlBar) {
  1418.             urlBar.value = "";
  1419.             urlBar.focus();
  1420.          }
  1421.    }
  1422.    else {
  1423.       // clear all timeouts before we remove the tab
  1424.       if (aTab.isClosing) clearTimeout(aTab.isClosing);
  1425.       if (aTab.mSelect) clearTimeout(aTab.mSelect);
  1426.       if (aTab.mouseHoverSelect && aTab.mFocusId) {
  1427.          clearTimeout(aTab.mFocusId);
  1428.       }
  1429.       if (aTab.mButtonId) clearTimeout(aTab.mButtonId);
  1430.  
  1431.       if (aTab.hasAttribute("busy"))
  1432.          this.getBrowserForTab(aTab).stop();
  1433.  
  1434.       this.removeTab(aTab, true);
  1435.       if (this.mTabContainer.childNodes.length == 1 && this.isBlankTab(this.mCurrentTab))
  1436.          setURLBarFocus();
  1437.       this.stopMouseHoverSelect(aTab);
  1438.    }
  1439. }
  1440.  
  1441. gBrowser.stopMouseHoverSelect = function(aTab) {
  1442.    // add extra delay after tab removed or after tab flip before we select by hover
  1443.    // to let the user time to move the mouse
  1444.    if (aTab.mouseHoverSelect) {
  1445.       function removeDelayAfterClose(browser) {
  1446.          browser.removeAttribute("preventMouseHoverSelect");
  1447.       }
  1448.       this.setAttribute("preventMouseHoverSelect",true);
  1449.       var delay = aTab.mouseHoverSelectDelay + 50;
  1450.       setTimeout(removeDelayAfterClose, delay, this);
  1451.    }
  1452. }
  1453.  
  1454. gBrowser.warnAboutClosingTabs =  function (whatToClose, tabPos, protectedTab, aDomain) {
  1455.    // try to cach call from other extensions to warnAboutClosingTabs
  1456.    if (typeof(whatToClose) == "boolean") {
  1457.       if (!whatToClose)
  1458.          protectedTab = this.mCurrentTab.hasAttribute("protected");
  1459.       whatToClose = whatToClose ? "All_onExit" : "AllBut";
  1460.    }
  1461.  
  1462.    var childNodes = this.mTabContainer.childNodes;
  1463.    var numTabs = childNodes.length;
  1464.    // calc the number of tab to close when there is protected tabs.
  1465.    var protectedTabs = this.mTabContainer.getElementsByAttribute("protected", true);
  1466.    var numProtected = protectedTabs.length;
  1467.    var shouldPrompt = 0;
  1468.    var prefs = ["extensions.tabmix.tabs.warnOnClose",
  1469.                 "extensions.tabmix.protectedtabs.warnOnClose",
  1470.                 "browser.tabs.warnOnClose"];
  1471.    if (whatToClose == "All_onExit") {
  1472.       if (numProtected > 0 && this.mPrefs.getBoolPref(prefs[1]))
  1473.          shouldPrompt = 2;
  1474.  
  1475.       if (numTabs > 1 && this.mPrefs.getBoolPref(prefs[2]))
  1476.          shouldPrompt = 3;
  1477.    }
  1478.    else if (numTabs > 1 && this.mPrefs.getBoolPref(prefs[0]))
  1479.       shouldPrompt = 1;
  1480.  
  1481.    if (shouldPrompt == 0)
  1482.       return true;
  1483.  
  1484.    var i, tabsToClose = 0;
  1485.    switch (whatToClose) {
  1486.       case "All":
  1487.          tabsToClose = numTabs - numProtected;
  1488.          break;
  1489.       case "All_onExit":
  1490.          tabsToClose = numTabs;
  1491.          break;
  1492.       case "AllBut":
  1493.          if (protectedTab)
  1494.             --numProtected;
  1495.          tabsToClose = numTabs - 1 - numProtected;
  1496.          break;
  1497.       case "Group":
  1498.          for ( i = numTabs - 1; i > -1; --i) {
  1499.             if (this.getBrowserForTab(childNodes[i]).currentURI.spec.indexOf(aDomain) != -1 &&
  1500.                   !childNodes[i].hasAttribute("protected"))
  1501.                tabsToClose++;
  1502.          }
  1503.          break;
  1504.       case "Right":
  1505.          for ( i = 0; i < protectedTabs.length; i++ )
  1506.             if (protectedTabs[i]._tPos <= tabPos)
  1507.                --numProtected;
  1508.          tabsToClose = numTabs - tabPos - 1 - numProtected;
  1509.          break;
  1510.       case "Left":
  1511.          for ( i = 0; i < protectedTabs.length; i++ )
  1512.             if (protectedTabs[i]._tPos >= tabPos)
  1513.                --numProtected;
  1514.          tabsToClose = tabPos - numProtected;
  1515.          break;
  1516.    }
  1517.  
  1518.    if (tabsToClose <= 1 && shouldPrompt < 2)
  1519.       return true;
  1520.  
  1521.    //default to true: if it were false, we wouldn't get this far
  1522.    var warnOnClose = { value:true };
  1523.    var bundle = this.mStringBundle;
  1524.  
  1525.    var message, messageKey, chkBoxLabel;
  1526.    var tmp_bundle = document.getElementById("tmp-string-bundle");
  1527.    if (shouldPrompt == 1 || numProtected == 0) {
  1528.       messageKey = (tabsToClose == 1) ? "tabs.closeWarningOneTab" : "tabs.closeWarningMultipleTabs";
  1529.       message = bundle.getFormattedString(messageKey, [tabsToClose]);
  1530.       chkBoxLabel = shouldPrompt == 1 ? bundle.getString("tabs.closeWarningPromptMe") :
  1531.                                         tmp_bundle.getString("window.closeWarning.1");
  1532.    }
  1533.    else {
  1534.       messageKey = "protectedtabs.closeWarning.";
  1535.       messageKey += (numProtected < tabsToClose) ? "3" : (numProtected == 1) ? "1" : "2";
  1536.       message = tmp_bundle.getFormattedString(messageKey, [tabsToClose, numProtected]);
  1537.       var chkBoxKey = shouldPrompt == 3 ? "window.closeWarning.1" : "protectedtabs.closeWarning.4";
  1538.       chkBoxLabel = tmp_bundle.getString(chkBoxKey);
  1539.    }
  1540.  
  1541.    var closeKey = (tabsToClose == 1) ? "tabs.closeButtonOne" : "tabs.closeButtonMultiple";
  1542.    var buttonLabel = shouldPrompt == 1 ? bundle.getString(closeKey) :
  1543.                                           tmp_bundle.getString("closeWindow.label");
  1544.  
  1545.    window.focus();
  1546.    var promptService = Cc["@mozilla.org/embedcomp/prompt-service;1"]
  1547.                                     .getService(Ci.nsIPromptService);
  1548.    var buttonPressed = promptService.confirmEx(window,
  1549.                                                 bundle.getString("tabs.closeWarningTitle"),
  1550.                                                 message,
  1551.                                                 (promptService.BUTTON_TITLE_IS_STRING * promptService.BUTTON_POS_0)
  1552.                                                 + (promptService.BUTTON_TITLE_CANCEL * promptService.BUTTON_POS_1),
  1553.                                                 buttonLabel,
  1554.                                                 null, null,
  1555.                                                 chkBoxLabel,
  1556.                                                 warnOnClose);
  1557.    var reallyClose = (buttonPressed == 0);
  1558.    // don't set the pref unless they press OK and it's false
  1559.    if (reallyClose && !warnOnClose.value) {
  1560.       this.mPrefs.setBoolPref(prefs[shouldPrompt - 1], false);
  1561.    }
  1562.  
  1563.    return reallyClose;
  1564. }
  1565.  
  1566. gBrowser.TMP_selectNewForegroundTab = function (aTab, aLoadInBackground, aUrl, addOwner) {
  1567.    var bgLoad = (aLoadInBackground != null) ? aLoadInBackground :
  1568.                   this.mPrefs.getBoolPref("browser.tabs.loadInBackground");
  1569.    if (!bgLoad) {
  1570.       // set new tab owner
  1571.       addOwner = addOwner != null ? addOwner : true;
  1572.       if (addOwner)
  1573.          aTab.owner = this.selectedTab;
  1574.       this.selectedTab = aTab;
  1575.       if (aUrl) {
  1576.         var testString = /^(about:blank|chrome:\/\/abouttab\/content\/text.html|chrome:\/\/abouttab\/content\/tab.html|chrome:\/\/google-toolbar\/content\/new-tab.html)/;
  1577.         if (testString.test(aUrl))
  1578.           setURLBarFocus();
  1579.       }
  1580.    }
  1581. }
  1582.  
  1583. gBrowser.getTabForBrowser = function (aBrowser) {
  1584.    return document.getAnonymousElementByAttribute(this, "linkedpanel", aBrowser.parentNode.id);
  1585. }
  1586.  
  1587. gBrowser.getTabForLastPanel = function () {
  1588.    return document.getAnonymousElementByAttribute(this, "linkedpanel", this.mPanelContainer.lastChild.id);
  1589. }
  1590.  
  1591. }} // end tablib
  1592.  
  1593. // make sure that our function don't break removeTab function
  1594. function TMP_onRemoveTab(tab, browser) {
  1595.   try {
  1596.       saveClosedTab(tab, browser);
  1597.       TMP_ClosedTabs.setButtonDisableState();
  1598.   }
  1599.   catch (ex) { TMP_ASSERT(ex, "ERROR in saveClosedTab"); }
  1600.  
  1601.   try {
  1602.       SessionManager.tabScrolled(tab);
  1603.   }
  1604.   catch (ex) { TMP_ASSERT(ex, "ERROR in SessionManager.tabScrolled"); }
  1605.  
  1606.   try {
  1607.       SessionManager.tabClosed(tab);
  1608.   }
  1609.   catch (ex) { TMP_ASSERT(ex, "ERROR in SessionManager.tabClosed"); }
  1610. }
  1611.  
  1612. function TMP_closeLastTab() {
  1613.   if (/^Mac/.test(navigator.platform) && window.location.href != getBrowserURL()) {
  1614.     closeWindow(true);
  1615.     return;
  1616.   }
  1617.   // browser.tabs.closeWindowWithLastTab exist only from Firefox 3.5
  1618.   if (gBrowser.tabContainer.childNodes.length > 1 ||
  1619.       !TMP_getBoolPref("", "browser.tabs.closeWindowWithLastTab",false))
  1620.     gBrowser.removeCurrentTab(true);
  1621.   else
  1622.     closeWindow(true);
  1623. }
  1624.  
  1625. function TMP_closeWindow(aCountOnlyBrowserWindows) {
  1626.   if (!gIsFirefox36 && !closeWindow(false))
  1627.      return false;
  1628.   
  1629.   // privatebrowsing from Firefox 3.5
  1630.   var inPrivateBrowsing = false;
  1631.   if (gIsFirefox35) {
  1632.     try {
  1633.       var pbSvc = Cc["@mozilla.org/privatebrowsing;1"]
  1634.                             .getService(Ci.nsIPrivateBrowsingService);
  1635.       inPrivateBrowsing = pbSvc.privateBrowsingEnabled;
  1636.     } catch(e) { }
  1637.   }
  1638.  
  1639.   var quitType = arguments.callee.caller.caller.name;
  1640.   var showPrompt;
  1641.   var windowtype  = aCountOnlyBrowserWindows ? "navigator:browser" : null;
  1642.   // make sure not to show here our prompt if BrowserGlue.prototype._onQuitRequest show prompt
  1643.   // we save browser.startup.page in SessionManager.observe  
  1644.   if (!inPrivateBrowsing && !(/^Mac/.test(navigator.platform)) && numberOfWindows(false, windowtype) == 1 &&
  1645.             window.document.documentElement.getAttribute("windowtype") == "navigator:browser" &&
  1646.             window.gBrowser.browsers.length > 1) {
  1647.      showPrompt = false;
  1648.      try {
  1649.        let browserStartupPref;
  1650.        if ("browserStartupPref" in SessionManager) {
  1651.          browserStartupPref = SessionManager.browserStartupPref;
  1652.          delete SessionManager.browserStartupPref;
  1653.        }
  1654.        else
  1655.          browserStartupPref = gTabmixPrefs.getIntPref("browser.startup.page");
  1656.        var sessionWillBeSaved = browserStartupPref == 3 ||
  1657.                                 gTabmixPrefs.getBoolPref("browser.sessionstore.resume_session_once");
  1658.        if (sessionWillBeSaved || !gTabmixPrefs.getBoolPref("browser.warnOnQuit"))
  1659.           showPrompt = true;
  1660.        // its can't be restart here, restart don't call closeWindow in Firefox 3.0
  1661.        else if (quitType == "restart")
  1662.           showPrompt = !gTabmixPrefs.getBoolPref("browser.warnOnRestart");
  1663.        else
  1664.           showPrompt = !gTabmixPrefs.getBoolPref("browser.tabs.warnOnClose");
  1665.      } catch (ex) {}
  1666.   }
  1667.   else
  1668.      showPrompt = true;
  1669.  
  1670.   var askBeforSave = quitType != "restartApp" && quitType != "restart";
  1671.   var isLastWindow = numberOfWindows() == 1;
  1672.   var result = SessionManager.deinit(isLastWindow, askBeforSave);
  1673.   var canClose = result.canClose;
  1674.   // we only show warnAboutClose if firefox or tabmix didn't do it already
  1675.   // if showPrompt is false then prompt was shown by firefox code from BrowserGlue.prototype._onQuitRequest
  1676.   // or from SessionManager.deinit
  1677.   if (canClose && showPrompt && result.showMorePrompt) {
  1678.       var pref = "extensions.tabmix.warnAboutClosingTabs.timeout";
  1679.       var startTime = new Date().valueOf();
  1680.       var oldTime = gTabmixPrefs.prefHasUserValue(pref) ? gTabmixPrefs.getCharPref(pref) : 0;
  1681.       canClose = gBrowser.warnAboutClosingTabs("All_onExit");
  1682.       gTabmixPrefs.setCharPref(pref, oldTime*1 + (new Date().valueOf() - startTime));
  1683.   }
  1684.  
  1685.   SessionManager.windowIsClosing(canClose, isLastWindow, result.saveSession, result.removeClosedTabs);
  1686.  
  1687.   return canClose;
  1688. }
  1689.  
  1690. function TMP_contentAreaOnDrop(aEvent, aUri, aPostData) {
  1691.   var where;
  1692.   var browser = gBrowser.getBrowserForDocument(aEvent.target.ownerDocument);
  1693.   if (browser && aUri != browser.currentURI.spec) {
  1694.     var tab = gBrowser.getTabForBrowser(browser);
  1695.     var isCopy = "dataTransfer" in aEvent ? (aEvent.dataTransfer.dropEffect == "copy") : (aEvent.ctrlKey || aEvent.metaKey);
  1696.     if (!isCopy && tab.getAttribute("locked") &&
  1697.                   !gBrowser.isBlankNotBusyTab(tab) && !isUrlForDownload(aUri)) {
  1698.       where = "tab";
  1699.     }
  1700.   }
  1701.   if (where == "tab")
  1702.     gBrowser.loadOneTab(aUri, null, null, aPostData, false, false);
  1703.   else
  1704.     loadURI(aUri, null, aPostData, false);
  1705. }
  1706.  
  1707. var _BrowserToolboxCustomizeDone;
  1708. var _bottomPosition = false;
  1709. function TMP_BrowserToolboxCustomizeDone() {
  1710.   var urlbar = document.getElementById("urlbar");
  1711.   // onblur attribut e reset each time we exit ToolboxCustomize
  1712.   if (urlbar) {
  1713.     var blur = urlbar.getAttribute("onblur") || "";
  1714.     if (blur.indexOf("TMP_urlBarOnBlur") == -1)
  1715.       urlbar.setAttribute("onblur", blur + "TMP_urlBarOnBlur();")
  1716.   }
  1717.  
  1718.   if (gIsFirefox35 && urlbar) {
  1719.     var _handleCommand = urlbar.handleCommand.toString();
  1720.     if (_handleCommand.indexOf("TMP_BrowserLoadURL") == -1) {
  1721.       if ("objURLsuffix" in window)
  1722.         urlbar._canonizeURL = objURLsuffix.canonizeUrl;
  1723.       // set altDisabled if Suffix extension installed
  1724.       eval("urlbar.handleCommand ="+ _handleCommand.replace(
  1725.         'var [url, postData] = this._canonizeURL(aTriggeringEvent);',
  1726.         'var _data = this._canonizeURL(aTriggeringEvent); \
  1727.          var altDisabled = _data.length == 3; \
  1728.          var [url, postData] = [_data[0], _data[1]];'
  1729.       ).replace(
  1730.         'if (aTriggeringEvent instanceof MouseEvent) {',
  1731.         'TMP_BrowserLoadURL(aTriggeringEvent,  postData, altDisabled); \
  1732.          return; \
  1733.          $&'
  1734.       ));
  1735.     }
  1736.   }
  1737.  
  1738.   if (_bottomPosition) {
  1739.     _bottomPosition = null;
  1740.     gTMPprefObserver.tabBarPositionChanged(1);
  1741.   }
  1742.  
  1743.   var tabsToolbaritem = document.getElementById("tabs-toolbaritem");
  1744.   if (tabsToolbaritem) {
  1745.     tabBarScrollStatus();
  1746.     checkBeforeAndAfter();
  1747.   }
  1748.  
  1749.   var searchbar = document.getElementById("searchbar");
  1750.   if (searchbar) {
  1751.     var _handleSearchCommand = searchbar.handleSearchCommand.toString();
  1752.     // we check browser.search.openintab also for search button click
  1753.     if (_handleSearchCommand.indexOf("forceNewTab") == -1) {
  1754.       eval("searchbar.handleSearchCommand ="+ _handleSearchCommand.replace(
  1755.        'where = whereToOpenLink(aEvent, false, true);',
  1756.        '$& \
  1757.         var forceNewTab = where == "current" && textBox._prefBranch.getBoolPref("browser.search.openintab"); \
  1758.         if (forceNewTab) where = "tab";'
  1759.       ));
  1760.     }
  1761.  
  1762.     var _doSearch = searchbar.doSearch.toString();
  1763.     if (_doSearch.indexOf("tabmixArg") == -1) {
  1764.       eval("searchbar.doSearch ="+ _doSearch.replace(
  1765.         'openUILinkIn(submission.uri.spec, aWhere, null, submission.postData);',
  1766.          <![CDATA[
  1767.            var tabmixArg = {backgroundPref: "extensions.tabmix.loadSearchInBackground"};
  1768.            var isBlankTab = gBrowser.isBlankNotBusyTab(gBrowser.mCurrentTab);
  1769.            var isLockTab = !isBlankTab && gBrowser.mCurrentTab.hasAttribute("locked");           
  1770.            if (aWhere == "current" && isLockTab)
  1771.              aWhere = "tab";
  1772.            else if ((/^tab/).test(aWhere) && isBlankTab)
  1773.              aWhere = "current"
  1774.            openUILinkIn(submission.uri.spec, aWhere, null, submission.postData, null, tabmixArg);
  1775.          ]]>
  1776.       ));
  1777.     }
  1778.   }
  1779.  
  1780.   var undocloseButton = document.getElementById("btn_undoclose");
  1781.   if (undocloseButton) {
  1782.     if (gIsFirefox35 && !undocloseButton.hasAttribute("ondrop")) {
  1783.       undocloseButton.setAttribute("ondrop", "nsDragAndDrop.drop(event, undocloseTabButtonObserver);");
  1784.       undocloseButton.setAttribute("ondragleave", "nsDragAndDrop.dragExit(event, undocloseTabButtonObserver);");
  1785.     }
  1786.     else if (!gIsFirefox35 && !undocloseButton.hasAttribute("ondragdrop")) {
  1787.       undocloseButton.setAttribute("ondragdrop", "nsDragAndDrop.drop(event, undocloseTabButtonObserver);");
  1788.       undocloseButton.setAttribute("ondragexit", "nsDragAndDrop.dragExit(event, undocloseTabButtonObserver);");
  1789.     }
  1790.   }
  1791.   if (gIsFirefox35)
  1792.     SessionManager.toggleRecentlyClosedWindowsButton();
  1793.  
  1794.   // Show Reload Every menu on Reload button
  1795.   gTMPprefObserver.showReloadEveryOnReloadButton();
  1796. }
  1797.  
  1798. function TMP_BrowserCustomizeToolbar() {
  1799.   if (gTabbarPosition == 1) {
  1800.     _bottomPosition = true;
  1801.     gTMPprefObserver.tabBarPositionChanged(0);
  1802.   }
  1803. }
  1804.  
  1805. function TMP_onViewToolbarsPopupShowing(aPopup, aFirstMenuItem) {
  1806.   // if the toolbar is not on the botton we have notiong to do here...
  1807.   if (gTabbarPosition != 1)
  1808.     return;
  1809.  
  1810.   var toolbar = document.getElementById("tabs-toolbar");
  1811.   if (toolbar) {
  1812.     var toolbarName = toolbar.getAttribute("toolbarname");
  1813.     var type = toolbar.getAttribute("type");
  1814.     if (toolbarName && type != "menubar") {
  1815.       var menuItem = document.createElement("menuitem");
  1816.       var toolbox = document.getElementById("navigator-toolbox");
  1817.       menuItem.setAttribute("toolbarindex", toolbox.childNodes.length);
  1818.       menuItem.setAttribute("type", "checkbox");
  1819.       menuItem.setAttribute("label", toolbarName);
  1820.       menuItem.setAttribute("accesskey", toolbar.getAttribute("accesskey"));
  1821.       menuItem.setAttribute("checked", toolbar.getAttribute("collapsed") != "true");
  1822.       aPopup.insertBefore(menuItem, aFirstMenuItem);
  1823.  
  1824.       menuItem.addEventListener("command", function() {
  1825.         var toolbar = document.getElementById("tabs-toolbar");
  1826.         toolbar.collapsed = !toolbar.collapsed;
  1827.         document.persist("tabs-toolbar", "collapsed");
  1828.       }, false);
  1829.     }
  1830.   }
  1831. }
  1832.  
  1833. function setURLBarFocus() {
  1834.   if (gURLBar)
  1835.     gURLBar.focus();
  1836. }
  1837.  
  1838. function dupScrollPosition(event) {
  1839.   var browser = this;
  1840.   var data = browser._scrollData;
  1841.   browser.removeEventListener('load', dupScrollPosition, true);
  1842.   var tab = gBrowser.getTabForBrowser(browser);
  1843.   if (tab && tab.parentNode)
  1844.     SessionManager.setScrollPosition(tab, browser, data, 15);
  1845.   delete browser._scrollData;
  1846. }
  1847.  
  1848. function menuItemTitle(entry) {
  1849.    if (entry.URI)
  1850.       return getTitleFromBookmark(entry.URI.spec, entry.title);
  1851.    return entry.title;
  1852. }
  1853.  
  1854. function saveClosedTab(tab, browser) {
  1855.    if (TMP_ClosedTabs.ssIsON)
  1856.       return;
  1857.  
  1858.    var maxTabsUndo = gTabmixPrefs.getIntPref("browser.sessionstore.max_tabs_undo");
  1859.    if (tabxPrefs.getBoolPref("undoClose") && maxTabsUndo > 0 && !gBrowser.isBlankBrowser(browser)) {
  1860.       var bContent = browser.contentWindow;
  1861.       var zoomFactor = browser.docShell.contentViewer ? browser.markupDocumentViewer.textZoom : 1;
  1862.       gBrowser.closedTabs.unshift({
  1863.          pos:        tab._tPos,
  1864.          history:    browser.sessionHistory,
  1865.          title:      tab.getAttribute("label"),
  1866.          image:      tab.getAttribute("image"),
  1867.          properties: SessionData.getTabProperties(tab),
  1868.          scroll:     bContent.scrollX + "," + bContent.scrollY + "," + zoomFactor
  1869.       })
  1870.    }
  1871.    if (gBrowser.closedTabs.length > maxTabsUndo)
  1872.       gBrowser.closedTabs.splice(maxTabsUndo, gBrowser.closedTabs.length - maxTabsUndo);
  1873. }
  1874.  
  1875. var autoReloadTabID = 0;
  1876. var gAutoReloadDialogAccepted;
  1877.  
  1878. function autoReloadDialogResult(accepted){
  1879.   gAutoReloadDialogAccepted = accepted;
  1880. }
  1881.  
  1882. function setupAutoReload(aTab) {
  1883.   aTab.autoReloadEnabled = false;
  1884.   aTab.autoReloadTime = tabxPrefs.getIntPref("reload_time");
  1885.   aTab.autoReloadTimerID = null;
  1886.   aTab.postDataAcceptedByUser = false;
  1887.   autoReloadTabID++;
  1888. }
  1889.  
  1890. function reloadPage(aTab) {
  1891.   if (aTab == null || !aTab.parentNode)
  1892.     return;
  1893.  
  1894.   if (aTab.autoReloadEnabled == false ){
  1895.     aTab.postDataAcceptedByUser = false;
  1896.     return;
  1897.   }
  1898.  
  1899.   var browser = gBrowser.getBrowserForTab(aTab);
  1900.   var webNav = browser.webNavigation;
  1901.   var postData, referrer;
  1902.   try {
  1903.     var sh = webNav.sessionHistory;
  1904.     if (sh) {
  1905.       var entry = sh.getEntryAtIndex(sh.index, false);
  1906.       postData = entry.QueryInterface(Components.interfaces.nsISHEntry).postData;
  1907.       referrer = entry.QueryInterface(Components.interfaces.nsISHEntry).referrerURI;
  1908.  
  1909.       if (postData == null)
  1910.         webNav = sh.QueryInterface(nsIWebNavigation);
  1911.       else if (!aTab.postDataAcceptedByUser) {
  1912.         var params = Components.classes['@mozilla.org/embedcomp/dialogparam;1'].createInstance(Components.interfaces.nsIDialogParamBlock);
  1913.         var stringBundle = document.getElementById("tmp-string-bundle");
  1914.         params.SetString(12, stringBundle.getString('confirm_autoreloadPostData_title'));
  1915.         params.SetString(0,  stringBundle.getString('confirm_autoreloadPostData'));
  1916.         params.SetString(2, 'alert-icon');
  1917.         params.SetInt(2, 2);
  1918.         window.openDialog('chrome://global/content/commonDialog.xul', '_blank', 'chrome,modal,centerscreen', params);
  1919.  
  1920.         if (params.GetInt(0) == 0)
  1921.           aTab.postDataAcceptedByUser = true;
  1922.         else {
  1923.           aTab.autoReloadEnabled = false;
  1924.           return;
  1925.         }
  1926.       }
  1927.     }
  1928.   } catch (e) {  }
  1929.  
  1930.   browser.curScrollX = browser.contentWindow.scrollX;
  1931.   browser.curScrollY = browser.contentWindow.scrollY;
  1932.   var loadFlags = nsIWebNavigation.LOAD_FLAGS_BYPASS_HISTORY | nsIWebNavigation.LOAD_FLAGS_BYPASS_PROXY | nsIWebNavigation.LOAD_FLAGS_BYPASS_CACHE;
  1933.   if (postData)
  1934.     webNav.loadURI(webNav.currentURI.spec, loadFlags, referrer, postData, null);
  1935.   else
  1936.     webNav.reload(loadFlags);
  1937. }
  1938.  
  1939. /* DEPRECATED */
  1940. var gIsFirefox3 = true;
  1941. function TMP_BrowserCloseWindow() { tmLog(TMP_D_MSG, true); }
  1942. function _confirmOpenTabs(numTabsToOpen) {
  1943.   tmLog(TMP_D_MSG, true);
  1944.   return PlacesController.prototype._confirmOpenTabs(numTabsToOpen);
  1945. }
  1946. function setTextZoom() { tmLog(TMP_D_MSG, true); }
  1947. function adjustSafebrowsingDimArea() { tmLog(TMP_D_MSG, true); }
  1948. function openMultipleLinks() { tmLog(TMP_D_MSG, true); }
  1949. var gPref = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefBranch2);
  1950. function TMP_SearchLoadURL() { tmLog(TMP_D_MSG, true); }
  1951.